import numpy

# 构造
def numpy_test1():
    # 生成两行三列的全0矩阵
    a = numpy.zeros((2, 3))
    print(a)
    
# 构造
def numpy_test2():
    # 填充生成两行三列的全1矩阵
    c = numpy.full((2, 3), 1, dtype=float)
    print(c)
    
# 构造
def numpy_test3():
    # 按照标准正态分布生成2行3列矩阵
    mat1 = numpy.random.randn(2, 3)
    print(f"mat1={mat1}")
    
# 构造
def numpy_test4():
    # 由python内list构建numpy矩阵
    list1 = [[1, 2], [3, 4], [5, 6]]
    d = numpy.array(list1)
    print(d)
    
# 元素访问
def numpy_test5():
    # 由python内list构建numpy矩阵
    list1 = [[1, 2], [3, 4], [5, 6]]
    d = numpy.array(list1)
    print(d)
    
    # 访问某行某列的元素
    print(d[0, 0]) #0行0列

    # 访问某列元素
    print(d[:, 0]) # :<=>所有行

    # 访问某行元素
    print(d[0, :]) # :<=>所有列
    
def numpy_test5_2():
    data = list(range(1 * 3 * 2 * 3))
    tensor = numpy.array(data)
    tensor = tensor.reshape((1, 3, 2, 3))
    tensor = numpy.squeeze(tensor)
    print(tensor)
    
    # [:-1, :, :]取除了最后一层的所有层
    result = tensor[:-1, :, :]
    print(result)
    
# 内部求和
def numpy_test6():
    c = numpy.array([[1, 2], 
                     [3, 4]])
    print(f"c={c}")
    
    # 按第0个轴方向求和，输出1行3列的向量
    print(numpy.sum(c, axis=0, keepdims=True))
    
    # 按第1个轴方向求和，输出2行1列的向量
    print(numpy.sum(c, axis=1, keepdims=True))
    
    d = numpy.array([
                    [[1, 2],
                     [3, 4]],
                    [[5, 6],
                     [7, 8]]
                    ])
    print(f'd.shape={d.shape}')
    
    d0 = numpy.sum(d, axis=0, keepdims=True)
    print(d0) #两个矩阵相加，输出一个张量，形状为(1, 2, 2)
    
    d1 = numpy.sum(d, axis=0, keepdims=False)
    print(d1) #两个矩阵相加，输出两个矩阵，形状为(2, 2)
    
def numpy_test6_2():
    data = list(range(1 * 3 * 2 * 3))
    tensor = numpy.array(data)
    tensor = tensor.reshape((1, 3, 2, 3))
    tensor = numpy.squeeze(tensor)
    print(tensor)
    
    div = numpy.sum(tensor, axis=0) #张量按层的方向求和<=>多层矩阵按位置元素求和，得到一个矩阵
    print(div)
    
    result = tensor / div #张量除以矩阵<=>每层矩阵除以该矩阵，得到张量
    print(result)
    
    
# 矩阵内部求均值
def numpy_test7():
    c = numpy.array([[1, 2], 
                     [3, 4]])
    
    # 矩阵元素求均值
    print(c.mean(axis=0, keepdims=True)) #第0个轴方向(竖向)求均值，输出[2 ,3]
    print(c.mean(axis=1, keepdims=True)) #第1个轴方向(横向)求均值，输出[1.5, 3.5]
    print(c.mean()) #所有值求均值
    
# 两个矩阵dot运算
def numpy_test8():
    a = numpy.array([1, 2])
    b = numpy.array([3, 4])
    c = numpy.array([[1, 2], 
                     [3, 4]])
    d = numpy.array([[5, 6], 
                     [7, 8]])
    
    # 点乘
    print(numpy.dot(a, b)) #输出11=1x3+2x4
    print(numpy.dot(c, d)) #输出矩阵乘法结果
    
# 两个矩阵乘法运算
def numpy_test9():
    c = numpy.array([[1, 2], 
                     [3, 4]])
    d = numpy.array([[5, 6], 
                     [7, 8]])
    
    # 矩阵乘法
    print(c @ d) # python标准语法
    print(numpy.matmul(c, d)) #numpy矩阵乘法函数
    
# 矩阵和常数的加法(每个元素都加这个常量)
def numpy_test10():
    c = numpy.array([[1, 2], 
                     [3, 4]])
    
    # 矩阵加一个常量
    print(c + 1)
    
# 矩阵和常数的乘法(每个元素都乘以这个常量)
def numpy_test11():
    c = numpy.array([[1, 2], 
                     [3, 4]])
    
    # 矩阵乘以一个常量
    print(c * 3)
    
# 矩阵transpose(改变维度排序) <=> 矩阵转置
def numpy_test12():
    c = numpy.array([[1, 2], 
                     [3, 4],
                     [5, 6]])
    print(c) #默认维度排序0,1
    print(c.transpose(0, 1)) #默认维度排序0,1
    print(c.transpose(1, 0)) #转换后的维度排序1,0
    
# 张量改变维度排序
def numpy_test13():
    c = numpy.zeros((2, 3, 4))
    
    # 赋值
    value = 1
    for i in range(2):
        for j in range(3):
            for k in range(4):
                c[i, j, k] = value
                value = value + 1
                
    print(c) #2个3行4列的矩阵
    
    result = c.transpose(2, 1, 0)
    print(result) #4个3行两列的矩阵
    for i in range(4):
        for j in range(3):
            for k in range(2):
                print(f"result[{i}, {j}, {k}]={result[i, j, k]}")
    
# 矩阵reshape改变矩阵形状，里面的元素按原排序填充
def numpy_test14():
    c = numpy.array([[1, 2], 
                     [3, 4],
                     [5, 6]])
    print(c)
    
    '''
    结果
    [[1 2 3]
    [4 5 6]]
    '''
    # print(c.reshape((2, 3)))
    print(c.reshape([2, 3]))
    
# 按条件筛选，返回坐标
def numpy_test15():
    c = numpy.array([[1, 2], 
                     [3, 4],
                     [5, 6]])
    print(c)
    
    rows, cols = numpy.where(c > 3)
    print(rows)
    print(cols)
    
    i = 0
    while i < len(rows):
        print(c[rows[i], cols[i]]) #输出4，5，6
        i = i + 1
    
# linespace函数(区间等分)
def numpy_test16():
    x = numpy.linspace(-1, 1, 5) #[-1,1]等分为5个元素[-1.  -0.5  0.   0.5  1. ]
    print(x)
    
    y = numpy.linspace(-1, 1, 10) #[-1,1]等分为10个元素
    print(y)
    
# 使用numpy进行向量卷积运算
def numpy_test17():
    x = numpy.arange(1, 5, 1)
    y = numpy.arange(3, 8, 1)
    print(f"x={x}")
    print(f"y={y}")
    print(f"full mode={numpy.convolve(x, y, mode='full')}") #滑动向量有交集就计算模式
    print(f"valid mode={numpy.convolve(x, y, mode='valid')}") #滑动向量边界不超出就计算模式
    print(f"same mode={numpy.convolve(x, y, mode='same')}") #输出向量长度=输入向量长度最大值 模式
    
# numpy的exp算法：e^x
def numpy_test18():
    x = numpy.random.rand(2, 3, 4)
    print(f"x={x}")
    print(f"exp(x)={numpy.exp(x)}")
    
# 按位置访问
def numpy_test19():
    a = numpy.random.randn(2, 2)
    b = numpy.zeros((2, 2))
    print(f"a={a}")
    print(f"b={b}")
    
    r, c = a.shape
    i = 0
    while i < r:
        j = 0
        while j < c:
            b[i, j] = a[i, j]
            j = j + 1
            
        i = i + 1
    
    print(f"b={b}")
    
# 从数据序列构造张量(内容连续，分配到2x2x2x3的张量)
def numpy_test20():
    vector = list(range(24))
    print(vector)
    
    tensor = numpy.array(vector)
    print(tensor)
    
    new_tensor = tensor.reshape(2, 2, 2, 3)
    print(new_tensor)

# 计算模拟
def numpy_test21():
    vector = list(range(12))
    print(vector)
    
    tensor = numpy.array(vector)
    print(tensor)
    
    tensor1 = tensor.reshape(1, 2, 2, 3)
    print(tensor1)
    
    # 降维
    tensor2 = tensor1.reshape(2, 2, 3)
    
    # 一维视图
    print(f"tensor2.ravel={tensor2.ravel()}")
    
    # 打印，逐个元素访问
    for index, value in numpy.ndenumerate(tensor2):
        print(f"index={index},value={value}")
    
    # 张量元素做指数，求新张量
    tensor3 = numpy.exp(tensor2)
    print(f"tensor3={tensor3}")
    
    # 一维视图
    print(f"tensor3.ravel={tensor3.ravel()}")
    
    # # 打印，逐个元素访问
    # for i in range(100):
    #     print(f"after exp,i={i},data={tensor3.flat[i]}")


if __name__ == "__main__":
    numpy_test5_2()
    # numpy_test6()
    # numpy_test6_2()
    # numpy_test7()
    # numpy_test10()
    # numpy_test11()
    # numpy_test12()
    # numpy_test13()
    # numpy_test14()
    # numpy_test15()
    # numpy_test16()
    # numpy_test17()
    # numpy_test18()
    # numpy_test19()
    # numpy_test20()
    # numpy_test21()
    
    exit(0)